class Scenario1 : public Scenario {
protected:
	void init();
	bool termCondition();
	void arrivalHandler(entity e);
	void serviceFinishHandler(Server server);
};
void Scenario1::init() {
	report = arguments.report;
	file = arguments.file;
	serverMgr.newServer().serviceRate() = arguments.serviceRate;
	arrivalRate = arguments.arrivalRate;
	queueMgr.newQueue(arguments.queueType, arguments.capacity);
}

bool Scenario1::termCondition() {
	return serverMgr.totalServed() >= arguments.termCondition;
}
void Scenario1::arrivalHandler(entity en) {
	Server server;
	server = serverMgr.getServer(0);
	assign2Queue(en,0,clock);
	if (server.isIdle() == true) {
		assign2Server(queueMgr.getQueue(0).dequeue(clock),0,clock);
	}
}
void Scenario1::serviceFinishHandler(Server server) {
	Queue queue;
	server.deserver(clock);
	queue = queueMgr.getQueue(0);
	if (queue.getCount() >= 1) {
		assign2Server(queue.dequeue(clock),server.getId(),clock);
	}
}
class Scenario2a : public Scenario {
protected:
	void init();
	bool termCondition();
	void arrivalHandler(entity e);
	void serviceFinishHandler(Server server);
};
void Scenario2a::init() {
	report = arguments.report;
	file = arguments.file;
	serverMgr.newServer().serviceRate() = arguments.serviceRate;
	serverMgr.newServer().serviceRate() = arguments.serviceRate;
	serverMgr.newServer().serviceRate() = arguments.serviceRate;
	arrivalRate = arguments.arrivalRate;
	queueMgr.newQueue(arguments.queueType, arguments.capacity);
}

bool Scenario2a::termCondition() {
	return serverMgr.totalServed() >= arguments.termCondition;
}
void Scenario2a::arrivalHandler(entity en) {
	unsigned i;
	assign2Queue(en,0,clock);
	for (i = 0; i < serverMgr.getCount(); i++) {
		if (serverMgr.getServer(i).isIdle() == true) {
			assign2Server(queueMgr.getQueue(0).dequeue(clock),i,clock);
			break;
		}
	}
}
void Scenario2a::serviceFinishHandler(Server server) {
	Queue queue;
	server.deserver(clock);
	queue = queueMgr.getQueue(0);
	if (queue.getCount() >= 1) {
		assign2Server(queue.dequeue(clock),server.getId(),clock);
	}
}
class Scenario2c : public Scenario {
protected:
	void init();
	bool termCondition();
	void arrivalHandler(entity e);
	void serviceFinishHandler(Server server);
};
void Scenario2c::init() {
	report = arguments.report;
	file = arguments.file;
	serverMgr.newServer().serviceRate() = 3 * arguments.serviceRate;
	arrivalRate = arguments.arrivalRate;
	queueMgr.newQueue(arguments.queueType, arguments.capacity);
}
bool Scenario2c::termCondition() {
	return serverMgr.totalServed() >= arguments.termCondition;
}
void Scenario2c::arrivalHandler(entity en) {
	Server server;
	server = serverMgr.getServer(0);
	assign2Queue(en,0,clock);
	if (server.isIdle() == true) {
		assign2Server(queueMgr.getQueue(0).dequeue(clock),0,clock);
	}
}
void Scenario2c::serviceFinishHandler(Server server) {
	Queue queue;
	server.deserver(clock);
	queue = queueMgr.getQueue(0);
	if (queue.getCount() >= 1) {
		assign2Server(queue.dequeue(clock),server.getId(),clock);
	}
}
class Scenario2bUNIF : public Scenario {
protected:
	void init();
	bool termCondition();
	void arrivalHandler(entity e);
	void serviceFinishHandler(Server server);
};
void Scenario2bUNIF::init() {
	report = arguments.report;
	file = arguments.file;
	serverMgr.newServer().serviceRate() = arguments.serviceRate;
	serverMgr.newServer().serviceRate() = arguments.serviceRate;
	serverMgr.newServer().serviceRate() = arguments.serviceRate;
	arrivalRate = arguments.arrivalRate;
	queueMgr.newQueue(arguments.queueType, arguments.capacity);
	queueMgr.newQueue(arguments.queueType, arguments.capacity);
	queueMgr.newQueue(arguments.queueType, arguments.capacity);
}

bool Scenario2bUNIF::termCondition() {
	return serverMgr.totalServed() >= arguments.termCondition;
}
void Scenario2bUNIF::arrivalHandler(entity en) {
	unsigned i;
	i = (unsigned) unifRand(0,queueMgr.getCount());
	assign2Queue(en,i,clock);
	if (serverMgr.getServer(i).isIdle() == true) {
		assign2Server(queueMgr.getQueue(i).dequeue(clock),i,clock);
	}
}
void Scenario2bUNIF::serviceFinishHandler(Server server) {
	Queue queue;
	server.deserver(clock);
	queue = queueMgr.getQueue(server.getId());
	if (queue.getCount() >= 1) {
		assign2Server(queue.dequeue(clock),server.getId(),clock);
	}
}
class Scenario2bRR : public Scenario {
protected:
	void init();
	bool termCondition();
	void arrivalHandler(entity e);
	void serviceFinishHandler(Server server);
};
void Scenario2bRR::init() {
	report = arguments.report;
	file = arguments.file;
	serverMgr.newServer().serviceRate() = arguments.serviceRate;
	serverMgr.newServer().serviceRate() = arguments.serviceRate;
	serverMgr.newServer().serviceRate() = arguments.serviceRate;
	arrivalRate = arguments.arrivalRate;
	queueMgr.newQueue(arguments.queueType, arguments.capacity);
	queueMgr.newQueue(arguments.queueType, arguments.capacity);
	queueMgr.newQueue(arguments.queueType, arguments.capacity);
}

void Scenario2bRR::arrivalHandler(entity en) {
	unsigned i;
	i = en.getId() % queueMgr.getCount();
	assign2Queue(en,i,clock);
	if (serverMgr.getServer(i).isIdle() == true) {
		assign2Server(queueMgr.getQueue(i).dequeue(clock),i,clock);
	}
}
bool Scenario2bRR::termCondition() {
	return serverMgr.totalServed() >= arguments.termCondition;
}
void Scenario2bRR::serviceFinishHandler(Server server) {
	Queue queue;
	server.deserver(clock);
	queue = queueMgr.getQueue(server.getId());
	if (queue.getCount() >= 1) {
		assign2Server(queue.dequeue(clock),server.getId(),clock);
	}
}
class Scenario2bSQF : public Scenario {
protected:
	void init();
	bool termCondition();
	void arrivalHandler(entity e);
	void serviceFinishHandler(Server server);
};
void Scenario2bSQF::init() {
	report = arguments.report;
	file = arguments.file;
	serverMgr.newServer().serviceRate() = arguments.serviceRate;
	serverMgr.newServer().serviceRate() = arguments.serviceRate;
	serverMgr.newServer().serviceRate() = arguments.serviceRate;
	arrivalRate = arguments.arrivalRate;
	queueMgr.newQueue(arguments.queueType, arguments.capacity);
	queueMgr.newQueue(arguments.queueType, arguments.capacity);
	queueMgr.newQueue(arguments.queueType, arguments.capacity);
}

void Scenario2bSQF::arrivalHandler(entity en) {
	unsigned i,sqec,sqn=0,j;
	bool *issq;
	issq = new bool[queueMgr.getCount()];
	sqec = queueMgr.getQueue(0).getCount();
	for (i = 1; i < queueMgr.getCount(); i++) {
		unsigned qec;
		qec = queueMgr.getQueue(i).getCount();
		if (qec < sqec) {
			sqec=qec;
		}
	}
	for (i = 0; i < queueMgr.getCount(); i++) {
		issq[i] = false;
		if ( queueMgr.getQueue(i).getCount() == sqec ) {
			issq[i] = true;
			sqn++;
		}
	}
	j = (unsigned) unifRand(0,sqn);
	for (i = 0; i < queueMgr.getCount(); i++) {
		if (issq[i]) {
			if (j == 0) {
				break;
			}
			else {
				j--;
			}
		}
	}
	assign2Queue(en,i,clock);
	if (serverMgr.getServer(i).isIdle() == true) {
		assign2Server(queueMgr.getQueue(i).dequeue(clock),i,clock);
	}
	delete []issq;
}
bool Scenario2bSQF::termCondition() {
	return serverMgr.totalServed() >= arguments.termCondition;
}
void Scenario2bSQF::serviceFinishHandler(Server server) {
	Queue queue;
	server.deserver(clock);
	queue = queueMgr.getQueue(server.getId());
	if (queue.getCount() >= 1) {
		assign2Server(queue.dequeue(clock),server.getId(),clock);
	}
}
